<?php

/*
盘点单附表
*/

namespace Modules\Takestock\Http\Repositories;

use App\Services\KingDeeService;
use App\Services\UnitService;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Modules\Inventory\Repository\InventoryOrderRepository;
use Modules\Purchasing\Models\Provisional;
use Modules\Purchasing\Models\Provisionalschedule;
use Illuminate\Support\Facades\DB;
use Catch\Exceptions\FailedException;
use Modules\Base\Service\BoxService;
use Modules\Purchasing\Models\Supplier;
use Modules\Purchasing\Models\Supplierschedule;
use Modules\Purchasing\Models\Purchaseorder;
use Modules\Purchasing\Models\Purchaseorderschedule;
use Modules\Warehouse\Models\Storagelocation;
use Modules\Purchasing\Models\Inspectionlist;
use Modules\Purchasing\Models\Inspectionlistcheck;
use extend\services\warehouse\{warehouseService};//引入自定义类
use Modules\Intelligent\Http\Repositories\InspectionlistReget;
use Modules\Intelligent\Models\Otherstorage;
use Modules\Intelligent\Models\Otherstorageschedule;
use Modules\Intelligent\Models\Lotbinding;
use Modules\Takestock\Models\InventoryOrderDetailschedule;
use Modules\Inventory\Models\InventoryOrderDetail;
use Modules\Intelligent\Models\Otheroutboundfrom;
use Modules\Intelligent\Models\OtheroutboundfromSchedule;
use App\Enums\InvTransDocType;
use App\Services\InventoryService;
use App\Enums\InventoryOrderStatus;

class TakestockReget
{


    /*
    数据添加方法
    */
    public static function create(array $data)
    {

        $Otherstorage = new InventoryOrderDetailschedule;
        return self::createOrSave($Otherstorage, $data);
    }

    //数据添加方法
    public static function createOrSave(InventoryOrderDetailschedule $Otherstorage,$data)
    {
        try {
            //开始起事务
            DB::beginTransaction();

            foreach($data as $k=>$v){

                $inventoryOrder = InventoryOrderRepository::getOrderById($v['order_id']);

                if($inventoryOrder->status == InventoryOrderStatus::FINISH->value){
                    throw new \Exception('当前盘点单已完成盘点');
                }

                //设盘点单为盘点中
                $inventoryOrder->update([
                    'status' => InventoryOrderStatus::ING->value,
                ]);

                $newMaterial = $v['check'];

                if(empty($v['id'])){
                    //新增物料
                    $newdata = [
                        'order_id'      => $v['order_id'],
                        'material_no'   => $v['material_no'],
                        'wms_code'      => $v['wms_code'],
                        'location'      => $v['location'],
                        'lot_num'       => $v['lot_num'],
                        'stock_qty'     => $v['stock_qty'],
                        'remark'        => $v['remark'] ?? '',
                        'unit'          => $v['unit'],
                        'new_material'  => 3,
                        'creator_id'    => UnitService::getUserId(),
                        'created_at'    => time(),
                        'updated_at'    => time(),
                    ];

                    InventoryOrderDetail::insertGetId($newdata);

                }else{
                    $datares = InventoryOrderDetail::select('id','qty')->find($v['id']);

                    if($datares->qty != $v['stock_qty']){
                        $newMaterial =  2;
                    }

                    $datares->update([
                        'stock_qty'     =>$v['stock_qty'],
                        'new_material'  =>$newMaterial,
                    ]);
                }

                /*$datares = DB::table('inventory_order_detail')->select('id','qty')
                ->where('material_no',$v['material_no'])
                ->where('wms_code',$v['wms_code'])
                ->where('location',$v['location'])
                ->where('lot_num',$v['lot_num'])
                ->where('unit',$v['unit'])
                ->where('order_id',$v['order_id'])
                ->first();

                $new_material = $v['check'];
                //盘点没有的物料就新增数据
                if(empty($datares)){
                    $newdata['new_material'] = $new_material;
                    $insertGetId = DB::table('inventory_order_detail')->insertGetId( $newdata );
                    unset($newdata['new_material']);
                    $newdata['order_detail_id'] = $insertGetId;
                }else{
                    if($datares->qty != $v['stock_qty']){
                        $new_material =  2;
                    }
                    DB::table('inventory_order_detail')->where('id',$datares->id)->update([
                        'stock_qty'=>$v['stock_qty'],
                        'new_material'=>$new_material,
                    ]);
                    $newdata['order_detail_id'] = $datares->id;
                }
                InventoryOrderDetailschedule::insert( $newdata );*/
            }

            DB::commit();
            return [];
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }

    }

    //修改
    public static function createUpdate($data)
    {

        try {
            //开始起事务
            DB::beginTransaction();
            $Inspectionlist = Inspectionlist::query()->updateOrCreate(['id' => $data['inspectionlist_id']], [
                'inspectiontime'       => time()  ?? '',
                'method'       => $data['method']  ?? '',
                'gitquantity'       => $data['gitquantity']  ?? '',
                'quantityincoming'       => $data['quantityincoming']  ?? '',
                'inspectionresult'       => $data['inspectionresult']  ?? '',
                'decision'       => $data['decision']  ?? 0,
                'inspector_user'       => $data['creator_id']  ?? '',
            ]);

            $Inspectionlist->detailscheckAll()->createMany($data['detailscheck_all']);

            DB::commit();
            return ['code'=>1000,'message'=>'检验成功'];
        } catch (\Exception $e) {
            DB::rollBack();
            throw new FailedException('服务器飞出地球了请联系技术找回');
        }

    }

    /**
     * 查询一条数据
     *
     */
    public static function find($id)
    {
        return Provisional::query()->with('detailscheckAll')->find($id);
    }

    /**
     * @param $id
     * @return void
     */
    public static function delete($id)
    {

        try {
            //开始起事务
            DB::beginTransaction();

            Otherstorage::query()->where('id',$id)->delete();
            Otherstorageschedule::query()->where('otherstorage_id',$id)->delete();
            DB::commit();
            return '删除成功';
        } catch (\Exception $e) {
            DB::rollBack();
           throw new FailedException('服务器飞出地球了请联系技术找回');
        }


    }
     /**修改接口
     * @param $id
     * @return void
     */
    public static function auditupdate($id,$data)
    {

        try {
            //开始起事务
            DB::beginTransaction();
            Otherstorageschedule::query()->updateOrCreate(['id' => $id], [
                'quantity' => $data['quantity'],
            ]);
            // $resdata = Provisionalschedule::select('id','provisional_id')->where('provisional_id',$id)->get();
            // foreach($resdata as $k=>$v){
            //     $Inspectionlist = [];
            //     $Inspectionlist['inspectionnumber'] = 'LLJY'.date('Ymd',time()).makeSerial();
            //     $Inspectionlist = Inspectionlist::insertGetId($Inspectionlist);
            //     Otherstorageschedule::query()->updateOrInsert(['id' => $v['id']], [
            //     'inspectionlist_id'=>$Inspectionlist,
            //     ]);
            //     Provisional::query()->updateOrCreate(['id' => $v['provisional_id']], [
            //         'state' => 1,
            //     ]);
            // }

            DB::commit();
            return ['code'=>1000,'message'=>'修改成功'];
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }

    }

    /**
     * @param $id
     * @return void
     */
    public static function showApi($id)
    {
       $data = Otherstorage::select('othernumbers','incomingtype','incomingdate','state','state')
        ->where('id',$id)->first();


        if(empty($data)){
            throw new FailedException('数据出错');
        }else{

            $res = Otherstorageschedule::select('otherstorage_id','material_id','quantity','storagelocation','barcode')
            ->where('otherstorage_id',$id)
            ->get()
            ->toArray();

                foreach($res as $k=>$v){

                    $storagelocation = DB::table('storagelocation')
                    ->select('warehousecode','owning_id','repositoryname','person')
                    ->where('id',$v['storagelocation'])
                    ->first();

                    if(empty($storagelocation)){
                        throw new FailedException('仓库出错');
                    }

                    $res[$k]['warehousecode'] = $storagelocation->warehousecode;
                    $res[$k]['repositoryname'] = $storagelocation->repositoryname;

                    $stash = DB::table('stash')
                    ->select('fmaterial','fnumber','fname','fuseorgid_number','fuseorgid_name')
                    ->where('id',$storagelocation->owning_id)->first();

                    $res[$k]['fnumber_stash'] = $stash->fnumber;
                    $res[$k]['fname_stash'] = $stash->fname;

                    $material = DB::table('material')
                    ->select('fnumber','fname','fspecification','fspecification','funit_name','fuseorgid_name','fbaseproperty_number')
                    ->where('id',$v['material_id'])->first();

                    $res[$k]['fnumber'] = $material->fnumber;
                    $res[$k]['fname'] = $material->fname;
                    $res[$k]['fspecification'] = $material->fspecification;
                    $res[$k]['funit_name'] = $material->funit_name;
            }

            $data['detailscheck_all'] = $res;
            return ['code'=>1000,'message'=>'扫描成功','data'=>$data];

        }


    }

    /**盘点PDA 扫码
     * @param $id
     * @return void
    check 字段1、2、3、4
    1、绿色：完全对应上的；
    2、黄色：扫到有的物料，但数量有差异的；
    3、蓝色：盘点单上没有这个物料，实际扫到有这个物料；
    4、红色：盘点单上有这个物料，实际扫到没有这个物料 (没有盘点到)
     */
    public static function Barcodename($code,$data)
    {
        $check = 1;
        // $ifdata = DB::table('inventory_order_detail')->select('id')
        // ->where('order_id',$data['order_id'])
        // ->where('lot_num',$code)
        // ->first();
        // if(empty($ifdata)){
        //     return ['code'=>1000,'message'=>'该箱号不属于该条盘点单','data'=>[]];
        // }


        $inventory_order_detail = DB::table('inventory_order_detail as inorderdetail')
        ->join('inventory_order as inorder', 'inorder.id', '=', 'inorderdetail.order_id')
        ->select(
            'inorder.docno',
            'inorderdetail.order_id',
            'inorderdetail.material_no',
            'inorderdetail.wms_code',
            'inorderdetail.location',
            'inorderdetail.batch_no',
            'inorderdetail.lot_num',
            'inorderdetail.qty',
            'inorderdetail.unit'
            )
        ->where('inorderdetail.lot_num',$code)
        ->where('inorderdetail.order_id',$data['order_id'])
        ->where('inorderdetail.location',$data['location'])
        ->first();

        $inventory_order_detail = json_encode($inventory_order_detail);
        $inventory_order_detail = json_decode($inventory_order_detail,true);

        //盘点单没这个物料库存,新增加物料
        if(empty($inventory_order_detail)){
            $inventory_order = DB::table('inventory_order')
            ->select('docno')
            ->where('id',$data['order_id'])
            ->first();
            $inventory_order_detail = DB::table('inventory')
            ->select('org_code','location','material_no','unit','qty','lot_num')
            ->where('lot_num',$code)
            // ->where('order_id',$data['order_id'])
            ->where('location',$data['location'])
            ->first();
            $inventory_order_detail = json_encode($inventory_order_detail);
            $inventory_order_detail=json_decode($inventory_order_detail,true);
            $inventory_order_detail['docno'] = $inventory_order->docno;
            $check = 3;
        }else{
            $inventory = DB::table('inventory')
            ->select('org_code','location','material_no','unit','qty','lot_num')
            ->where('lot_num',$code)
            // ->where('order_id',$data['order_id'])
            ->where('location',$data['location'])
            ->first();
            if(empty($inventory)){
                $check = 4;
            }
        }

        $inventory_order_detail['check'] = $check;
        return ['code'=>1000,'message'=>'扫描成功','data'=>$inventory_order_detail];

    }



    /*审核接口
     * @param $id
     * @return void
     */
    public static function checkPdaApi($id)
    {
        $inventory_order = DB::table('inventory_order')
        ->select('org_code','docno','plan_id')
        ->where('id',$id)
        ->first();

       //总是数据汇总 汇总推送到金蝶
        $inventory_order_detail = InventoryOrderDetail::
        select('order_id','wms_code','material_no','unit',DB::raw('SUM(qty) as qty'),DB::raw('SUM(stock_qty) as stock_qty'))
        ->where('order_id',$id)
        ->groupby(['order_id','wms_code','material_no','unit'])
        ->get()
        ->toArray();
        if(empty($inventory_order_detail)||empty($inventory_order)){
            throw new FailedException('数据出错,无法获取数据');
        }



        $Model = [];
        $QW001 = '';
        $QW005 = '';
        $STK_MISCELLANEOUS = '';
        $STK_MisDelivery = '';

        foreach($inventory_order_detail as $k=>$v){

            $count = $v['stock_qty'] - $v['qty'];

            if($count != 0){
                //盘盈推送
                if($count > 0){
                    $QW001 = 'QW001';
                    $STK_MISCELLANEOUS = 'STK_MISCELLANEOUS';
                    $Model[$k]['FSRCSEQ'] = '';//物料源单行号
                    $Model[$k]['FMATERIALID'] = $v['material_no']; //SKU（传编码）
                    // $Model[$k]['FUNITID'] = $dataPurchaseorderschedule['funitid_number'];//单位（传编码）
                    $Model[$k]['FQTY'] = $count;
                    $Model[$k]['FGIVEAWAY'] = 'false';//是否赠品
                }

                //盘亏推送
                if($count < 0){
                    $QW005 = 'QW005';
                    $STK_MisDelivery = 'STK_MisDelivery';
                    $Model[$k]['FSRCSEQ'] = '';//物料源单行号
                    $Model[$k]['FMATERIALID'] = $v['material_no']; //SKU（传编码）
                    // $Model[$k]['FUNITID'] = $dataPurchaseorderschedule['funitid_number'];//单位（传编码）
                    $Model[$k]['FQTY'] = abs($count);
                    $Model[$k]['FGIVEAWAY'] = 'false';//是否赠品

                }
            }

        }

        //wms 库存出入库单据生成
        $inventorydata = InventoryOrderDetail::
        select('order_id','wms_code','material_no','unit','qty','stock_qty','lot_num','location')
        ->where('order_id',$id)
        //->groupby(['order_id','wms_code','material_no','unit'])
        ->get()
        ->toArray();

        try {
            //开始起事务
            DB::beginTransaction();
        //   p($inventorydata);
        //   exit;
            foreach($inventorydata as $k=>$v){
                $countorder = $v['stock_qty'] - $v['qty'];

                if($countorder != 0){

                   $storagelocation = DB::table('storagelocation')
                   ->select('warehousecode','owning_id','repositoryname','id')
                   ->where('warehousecode',$v['location'])
                   ->first();

                   $OtherstorageData = [
                      'storagelocation'=> $storagelocation->id,
                      'quantity'=> $countorder,
                      'barcode'=> $v['lot_num'],
                      'docno'=> $inventory_order->docno,
                  ];

                  if($countorder > 0){

                      $Otherstorage = new Otherstorage();
                       //盘盈加库存 生成其他入库单
                      $OtherstorageSingleData = self::OtherstorageSingle($Otherstorage,$OtherstorageData);

                      //加库存
                      $inventory = [
                          'org_code'=>$inventory_order->org_code,
                          'cargo_code'=>$inventory_order->org_code,
                          'supplier_code'=>$OtherstorageSingleData['othernumbers'],
                          'doc_id'=>$OtherstorageSingleData['id'],
                          'docno'=>$OtherstorageSingleData['othernumbers'],
                          'doc_type'=>InvTransDocType::OTHER_RECEIPT_OTHOR->value,
                          'material_no'=>$v['material_no'],//SKU
                          'location'=>$v['location'],
                          'qty'=>$countorder,
                          'unit'=>$v['unit'],
                          'lotnum'=>$v['lot_num'],
                      ];
                      $data = InventoryService::addInv($inventory);
                  }


                   //盘亏减库存 成其他出库单
                   if($countorder < 0){
                      $Otheroutboundfrom = new Otheroutboundfrom();

                      //盘亏减库存 生成其他入库单
                      $OtheroutboundfromOutData = self::OtheroutboundfromOut($Otheroutboundfrom,$OtherstorageData);

                      InventoryService::decInventory(
                          $inventory_order->org_code,
                          $OtheroutboundfromOutData['othernumbers'],
                          $OtheroutboundfromOutData['id'],
                          InvTransDocType::OTHER_DELIVERY_OTHOR->value,
                          $v['material_no'],//SKU
                          $v['location'],
                          $v['lot_num'],
                          $countorder,
                         $inventory_order->org_code,
                      );
                  }

               }
           }

           $order = [
               'FID'=>0,
               'FBillNo'=>$inventory_order->docno,
               'FDATE'=>date('Y-m-d H:i:s',time()),
               'FSRCBILLNO'=>'',
               'FEntity'=>$Model,
           ];
           if(!empty($QW001)&&!empty($STK_MISCELLANEOUS)){
                $order['FBILLTYPEID'] = $STK_MISCELLANEOUS;
                $order['FDESCRIPTION'] = $QW001;
           }
           if(!empty($QW005)&&!empty($STK_MisDelivery)){
                $order['FBILLTYPEID'] = $STK_MisDelivery;
                $order['FDESCRIPTION'] = $QW005;
           }

           //print_r($order);exit();

           //金蝶推送
          (new KingDeeService())->form('TVJB_DJWMSDJ')->invokeSave($order);

           DB::table('inventory_plan')
           ->where('id',$inventory_order->plan_id)
           ->update(['status'=>1]);

        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }

    }

    /*
    其他入库单生成
     */
    public static function OtherstorageSingle(Otherstorage $Otherstorage,$data)
    {

        $Otherstoragedata = [];
        $Otherstoragedata['othernumbers'] = 'QTRK'.date('Ymd',time()).makeSerial();
        $Otherstoragedata['area'] = 1;
        $Otherstoragedata['incomingtype'] = 5;
        $Otherstoragescheduledata['incomingdate'] = date('Y-m-d H:i:s',time());
        $Otherstoragescheduledata['remark'] = '盘盈入库';
        $Otherstoragescheduledata['docno'] = $data['docno'];
        $Otherstorage->fill($Otherstoragedata);
        $Otherstorage->save();
        $detailscheckOne = [];
        $detailscheckOne['material_id'] = null;
        $detailscheckOne['storagelocation'] = $data['storagelocation'];
        $detailscheckOne['quantity'] = $data['quantity'];
        $detailscheckOne['barcode'] = $data['barcode'];
        $detailscheckOne['otherstorage_id'] = $Otherstorage['id'];

        $Otherstorage->detailscheckOne()->insert( $detailscheckOne );

        return [
                'id'=>$Otherstorage['id'],
                'othernumbers'=>$Otherstoragedata['othernumbers']
            ];

    }

    /*
    其他出库单生成
     */
    public static function OtheroutboundfromOut(Otheroutboundfrom $Otheroutboundfrom,$data)
    {

            $Otheroutboundfromdata = [];
            $Otheroutboundfromdata['othernumbers'] = 'RTCK'.date('Ymd',time()).makeSerial();
            $Otheroutboundfromdata['area'] = 1;
            $Otheroutboundfromdata['incomingtype'] = 5;
            $Otheroutboundfromdata['deliverydate'] = date('Y-m-d H:i:s',time());
            $Otheroutboundfromdata['remark'] = '盘亏出库';
            $Otheroutboundfromdata['docno'] = $data['docno'];
            $Otheroutboundfrom->fill($Otheroutboundfromdata);
            $Otheroutboundfrom->save();
            $detailscheckOne = [];
            $detailscheckOne['storagelocation'] = $data['storagelocation'];
            $detailscheckOne['quantity'] = $data['quantity'];
            $detailscheckOne['barcode'] = $data['barcode'];
            $detailscheckOne['otheroutboundfrom_id'] = $Otheroutboundfrom['id'];
            $Otheroutboundfrom->detailscheckOne()->insert( $detailscheckOne );

            return [
                'id'=>$Otheroutboundfrom['id'],
                'othernumbers'=>$Otheroutboundfromdata['othernumbers']
            ];

    }






}
